{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "mineflayer.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "authorship_tag": "ABX9TyO3/6T3HTMoRxL7FoQ4bWrl",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/PrismarineJS/mineflayer/blob/master/docs/mineflayer.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2BAYqsdOgKNJ"
      },
      "source": [
        "# Using mineflayer in Python\n",
        "\n",
        "This is a tutorial on how to use mineflayer in Python. This example will connect you to the PrismarineJS test server. You can join it with prismarine-viewer or your Minecraft client at server IP **pjs.deptofcraft.com:25565**.\n",
        "\n",
        "If you're new to Jupyter Notebooks, you can press the \"Play\" button at the left of each code block to run it. Make sure that you run the blocks in a correct order."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qM2rVyxGf2Yv"
      },
      "source": [
        "## Setup"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K2ol06QOhL6s"
      },
      "source": [
        "First, make sure you have Python version 3.10 and Node.js version 18 or newer installed. You can get Node.js 18 it from https://nodejs.org/en/download or use [Node.js version managers](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#using-a-node-version-manager-to-install-nodejs-and-npm) like [`nvm`](https://github.com/creationix/nvm) or [`n`](https://github.com/tj/n) to install via the command line. Here we'll use `n` to install Node.js v18, then check our Node and Python versions:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8zCSpx8Bif5m",
        "outputId": "90ebac14-fc75-4136-f81d-34c5b2033da0"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "v18.17.1\n",
            "Python 3.10.12\n"
          ]
        }
      ],
      "source": [
        "# Use `n` to install nodejs 18, if it's not already installed:\n",
        "!curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | bash -s lts > /dev/null\n",
        "# Now write the Node.js and Python version to the console\n",
        "!node --version\n",
        "!python --version"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C7omnDs3lNaV"
      },
      "source": [
        "Now, we can use pip to install the `javascript` Python package to access Node.js libraries from Python."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DKnwzSZQ8Taf"
      },
      "source": [
        " !pip install javascript"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_RAKlcScgKtV"
      },
      "source": [
        "## Usage"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bxAdFbBfmdCd"
      },
      "source": [
        "If all is well, we can import the `javascript` library. We can then import the `require` function which works similarly to the `require` function in Node.js, but does the dependency management for us.\n",
        "\n",
        "You may notice the extra imports : On, Once, off and AsyncTask. These will be discussed later on.\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "54Lnq3aH4Tee"
      },
      "source": [
        "from javascript import require, On, Once, AsyncTask, once, off"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cy7-0cWxdhU8"
      },
      "source": [
        "We can now import Mineflayer"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "8jgkTVniDPUZ"
      },
      "source": [
        "mineflayer = require('mineflayer')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WBAj5rSkgjKX"
      },
      "source": [
        "Once we've done that, we can create a new `bot` instance, through the `createBot` function. You can see the docs for this function [here](https://github.com/PrismarineJS/mineflayer/blob/master/docs/api.md#bot). In the line below we specify a hostname and a port for the server, but do not pass any `auth` or `password` options, so it will connect to the server in offline mode.\n",
        "\n",
        "Below that, we also a call to the `once` function, which pauses the thread until an event has been triggered, then returns the output. Here, we print out  \"I spawned\" after the `login` event has been triggered on `bot`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "1gfZSAUCDVMg"
      },
      "outputs": [],
      "source": [
        "random_number = id([]) % 1000 # Give us a random number upto 1000\n",
        "BOT_USERNAME = f'colab_{random_number}'\n",
        "\n",
        "bot = mineflayer.createBot({ 'host': 'pjs.deptofcraft.com', 'port': 25565, 'username': BOT_USERNAME, 'hideErrors': False })\n",
        "\n",
        "# The spawn event\n",
        "once(bot, 'login')\n",
        "bot.chat('I spawned')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yvYZYbi0k8Za"
      },
      "source": [
        "If your bot spawned, we can now take a look at the bot's position"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "swMd1VvXYuKn"
      },
      "source": [
        "bot.entity.position"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EdSjlgmilZ3O"
      },
      "source": [
        "### Listening to events"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "23FTp0XrioMg"
      },
      "source": [
        "You can register an event handler with the `@On` or `@Once` decorator. This decorator takes two arguments, first it's the **Event Emitter** (the object that is sending events) and the second is the **event name**, what event you want to listen to. *Do not use the .on or .once methods on bot, use the decorators instead.*\n",
        "\n",
        "A decorator always has a function under it which is being decorated, which can have any name. The first parameter to any event emitter callback is the `this` argument. \n",
        "\n",
        "In the code below, we create an event emitter on `bot` that listens to `playerJoin` events, then print that out."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "s8QGmC4nHjnH"
      },
      "source": [
        "@On(bot, 'playerJoin')\n",
        "def end(this, player):\n",
        "  bot.chat('Someone joined!')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Onkn-TDsne9P"
      },
      "source": [
        "In Python, you cannot leave any arguments for an event handler callback blank like in JavaScript. Instead, you can use the asterisk (`*`) operator in Python to capture all remaining arguments to the right, much like the `...` rest/spread operator in JavaScript. The parameter with the asterisk will be a tuple containing the captured arguments.\n",
        "\n",
        "You can stop listening for events through an event handler by using the imported `off` function. It takes three parameters: the emitter, event name, and a reference to the Python function.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "S4y9qAe6oh8H"
      },
      "source": [
        "@On(bot, 'chat')\n",
        "def onChat(this, user, message, *rest):\n",
        "  print(f'{user} said \"{message}\"')\n",
        "\n",
        "  # If the message contains stop, remove the event listener and stop logging.\n",
        "  if 'stop' in message:\n",
        "    off(bot, 'chat', onChat)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OybQNxGAq4P2"
      },
      "source": [
        "You need to `off` all the event listeners you listen to with `@On`, else the Python process won't exit until all of the active event emitters have been off'ed. If you only need to listen once, you can use the `@Once` decroator like in the example above."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iOzZeWfHozeX"
      },
      "source": [
        "## Asynchronous tasks\n",
        "\n",
        "By default, all the operations you do run on the main thread. This means you can only do one thing at a time. To multitask, you can use the `@AsyncTask` decroator to run a function in a new thread, while not obstructing the main thread."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xJUk8b21pOzg"
      },
      "source": [
        "### Block breaking\n",
        "\n",
        "Take a look at the example below. Here we listen for a \"break\" trigger in a chat message, then we start digging the block underneath, while simultaneously sending a message that the bot has \"started digging\"."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yhoAlhAhpSTL"
      },
      "source": [
        "@On(bot, 'chat')\n",
        "def breakListener(this, sender, message, *args):\n",
        "  if sender and (sender != BOT_USERNAME):\n",
        "    if 'break' in message:\n",
        "      pos = bot.entity.position.offset(0, -1, 0)\n",
        "      blockUnder = bot.blockAt(pos)\n",
        "      if bot.canDigBlock(blockUnder):\n",
        "        bot.chat(f\"I'm breaking the '{blockUnder.name}' block underneath\")\n",
        "        # The start=True parameter means to immediately invoke the function underneath\n",
        "        # If left blank, you can start it with the `start()` function later on.\n",
        "        try:\n",
        "          @AsyncTask(start=True)\n",
        "          def break_block(task):\n",
        "            bot.dig(blockUnder)\n",
        "          bot.chat('I started digging!')\n",
        "        except Exception as e:\n",
        "          bot.chat(f\"I had an error {e}\")\n",
        "      else:\n",
        "        bot.chat(f\"I can't break the '{blockUnder.name}' block underneath\")\n",
        "    if 'stop' in message:\n",
        "      off(bot, 'chat', breakListener)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JMgoMA-MriAt"
      },
      "source": [
        "## Using mineflayer plugins\n",
        "\n",
        "Pick the plugin you want from the list [here](https://github.com/PrismarineJS/mineflayer#third-party-plugins), then `require()` it and register it to the bot. Some plugins have different ways to register to the bot, look at the plugin's README for usage steps."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OVAJCyxcsfig"
      },
      "source": [
        "### mineflayer-pathfinder\n",
        "\n",
        "`mineflayer-pathfinder` is a essential plugin that helps your bot move between places through A* pathfinding. Let's import it:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mH6eXm8TtTKh"
      },
      "source": [
        "pathfinder = require('mineflayer-pathfinder')\n",
        "bot.loadPlugin(pathfinder.pathfinder)\n",
        "# Create a new minecraft-data instance with the bot's version\n",
        "mcData = require('minecraft-data')(bot.version)\n",
        "# Create a new movements class\n",
        "movements = pathfinder.Movements(bot, mcData)\n",
        "# How far to be from the goal\n",
        "RANGE_GOAL = 1"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ju8MPkSauTBb"
      },
      "source": [
        "Now let's have create a goal for the bot to move to where another player wants, based on a chat message."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "8jIp8bxnudDK"
      },
      "source": [
        "bot.removeAllListeners('chat')\n",
        "@On(bot, 'chat')\n",
        "def handleMsg(this, sender, message, *args):\n",
        "  if sender and (sender != BOT_USERNAME):\n",
        "    bot.chat('Hi, you said ' + message)\n",
        "    if 'come' in message:\n",
        "      player = bot.players[sender]\n",
        "      target = player.entity\n",
        "      if not target:\n",
        "        bot.chat(\"I don't see you !\")\n",
        "        return\n",
        "      pos = target.position\n",
        "      bot.pathfinder.setMovements(movements)\n",
        "      bot.pathfinder.setGoal(pathfinder.goals.GoalNear(pos.x, pos.y, pos.z, RANGE_GOAL))\n",
        "    if 'stop' in message:\n",
        "      off(bot, 'chat', handleMsg)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K36XDP09k1aH"
      },
      "source": [
        "## Analyzing the world"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xK1Ww1ACmLZl"
      },
      "source": [
        "You can also interact with mineflayer through any other Python package."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5QatUqxeW6b_"
      },
      "source": [
        "Let's analyze some block frequencies..."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 417
        },
        "id": "k2XyRgzi8otw",
        "outputId": "a4de38b7-ec53-4e38-df0c-8b7f1067965e"
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "figure = plt.figure()\n",
        "axes = figure.add_axes([0,0,1,1])\n",
        "Vec3 = require('vec3').Vec3\n",
        "\n",
        "columns = bot.world.getColumns()\n",
        "block_freqs = {}\n",
        "for c in range(0, 3): # iterate through some of the loaded chunk columns\n",
        "  cc = columns[c].column\n",
        "  for y in range(1, 40):\n",
        "    for x in range(1, 16):\n",
        "      for z in range(1, 16):\n",
        "        block = cc.getBlock(Vec3(x, y, z))\n",
        "        if block.name in block_freqs:\n",
        "          block_freqs[block.name] += 1\n",
        "        else:\n",
        "          block_freqs[block.name] = 1\n",
        "\n",
        "print(block_freqs)\n",
        "axes.bar(block_freqs.keys(), block_freqs.values())\n",
        "plt.xticks(rotation=45)\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "{'bedrock': 1321, 'stone': 19258, 'diorite': 1123, 'lava': 64, 'granite': 1704, 'andesite': 1459, 'redstone_ore': 68, 'iron_ore': 156, 'coal_ore': 282, 'gold_ore': 26, 'lapis_ore': 5, 'dirt': 570, 'emerald_ore': 3, 'diamond_ore': 9, 'gravel': 66, 'air': 211}\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "q2IkKpXZzRiP"
      },
      "source": [
        "## Exiting the bot\n",
        "\n",
        "Once you're done, you can call `bot.quit()` or `bot.end()` to disconnect and stop the bot."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1-NxvPk1YuGw"
      },
      "source": [
        "bot.quit()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SpwlmlCBc90Q"
      },
      "source": [
        "## Read more\n",
        "\n",
        "* **API** - https://github.com/PrismarineJS/mineflayer/blob/master/docs/api.md\n",
        "* **Type Definitions** - https://github.com/PrismarineJS/mineflayer/blob/master/index.d.ts\n",
        "* FAQ - https://github.com/PrismarineJS/mineflayer/blob/master/docs/FAQ.md\n",
        "* JS tutorial - https://github.com/PrismarineJS/mineflayer/blob/master/docs/tutorial.md\n"
      ]
    }
  ]
}
